import download from "./utils/download.js";
import { promiseLimit } from "./utils/promise.js";
import config, { saveConfig } from "./config.js";

async function main() {
  try {
    if (config.page > 113) return console.log("结束");

    const data = await getPageData(config.page);
    await downloadAllPdfs(data.data);
    console.log("main 走完了");
  } catch (e) {
    console.error(e);
  }
}

function getPageData(page = 1) {
  return fetch(
    `https://www.exploit-db.com/papers?draw=${page}&columns%5B0%5D%5Bdata%5D=date_published&columns%5B0%5D%5Bname%5D=date_published&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=download&columns%5B1%5D%5Bname%5D=download&columns%5B1%5D%5Bsearchable%5D=false&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=description&columns%5B2%5D%5Bname%5D=description&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=false&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=platform_id&columns%5B3%5D%5Bname%5D=platform_id&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=false&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=lang_id&columns%5B4%5D%5Bname%5D=lang_id&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=author_id&columns%5B5%5D%5Bname%5D=author_id&columns%5B5%5D%5Bsearchable%5D=false&columns%5B5%5D%5Borderable%5D=false&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=desc&start=0&length=15&search%5Bvalue%5D=&search%5Bregex%5D=false&author=&lang=&platform=&_=1753852797580`,
    {
      headers: {
        accept: "application/json, text/javascript, */*; q=0.01",
        "accept-language": "zh-CN,zh;q=0.9",
        priority: "u=1, i",
        "sec-ch-ua":
          '"Not)A;Brand";v="8", "Chromium";v="138", "Google Chrome";v="138"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"',
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "x-requested-with": "XMLHttpRequest",
        cookie:
          "CookieConsent={stamp:%27-1%27%2Cnecessary:true%2Cpreferences:true%2Cstatistics:true%2Cmarketing:true%2Cmethod:%27implied%27%2Cver:1%2Cutc:1753852341977%2Cregion:%27SG%27}; _ga=GA1.3.923255135.1753852363; _gid=GA1.3.1299570420.1753852363; _ga_N0K6XSDCRJ=GS2.3.s1753852384$o1$g1$t1753852615$j51$l0$h0; XSRF-TOKEN=eyJpdiI6InRnellQQXRzeG9YV1l2V2k0TkhCc3c9PSIsInZhbHVlIjoibTB4NVdiajNEV2d3QjNQWmcwbVFOR1RIZlc2WXJBSHoyc2Z3c0xleXVBTUM4akwwZWxDWGtkR3h0b2ZEVjFpQiIsIm1hYyI6Ijk0YTNlZjJlZjZiMTAwNTYzODYxZTRjYWU5NGI3YTBkNGMwNjllMWZhMjY3ODE3Njk2YmE5ZjIxYjgzOWJmZTEifQ%3D%3D; exploit_database_session=eyJpdiI6IkhXWlRpcjVvTEVYTkJaYnJEXC9CbFRnPT0iLCJ2YWx1ZSI6Im4xTlBDZGczOFd0R2xrQjExcSs5dDcxMWRUbXVVVWZIMHlScER5WlJ2WGgwYktrUnVDUW5tM0l6U0RJUUx0TVgiLCJtYWMiOiJiZmZjNmU1N2ZhODAwMjI0YzI1Y2QwZmQ0NDA5MGVlZTBjZjY3NGY0MWJiNDY1YTg3MTc1YzEzMGEwZGQ5MTQxIn0%3D; _gat=1",
        Referer: "https://www.exploit-db.com/papers",
      },
      body: null,
      method: "GET",
    }
  ).then((response) => response.json()); // 将响应解析为 JSON
}

async function downloadAllPdfs(list) {
  await promiseLimit(
    list,
    async (item, index) => {
      console.log(
        `进度:${config.page}页 ${index + 1}/${list.length} (${Math.round(
          ((index + 1) / list.length) * 100
        )}%)`
      );

      await downloadPdf(item);
      config.pageIndex = index;

      // 等个3-10秒
      await new Promise((resolve) =>
        setTimeout(resolve, Math.random() * 3000 + 3000)
      );

      if (config.pageIndex == list.length - 1) {
        config.pageIndex = 0;
        config.page++;
        main();
        console.log("下一页");
      }

      console.log("保存配置");
      saveConfig();
    },
    {
      index: config.pageIndex,
      limit: 1,
    }
  );

  console.log("downloadAllPdfs");
}

async function downloadPdf(item) {
  console.log("downloadPdf");

  const match = item.download.match(/href="(\/download\/\d+)"/);
  const downloadPath = "https://www.exploit-db.com" + match[1]; // "/download/50552"
  console.log(downloadPath); // 输出: /download/50552
  await download(downloadPath, `output/${config.page}`).catch((e) => {
    console.error(e);

    if (!config.errors[config.page]) config.errors[config.page] = {};

    config.errors[config.page][downloadPath] = true;
    saveConfig();
  });
  console.log("下载完成");
}

// 捕获未捕获的异常
process.on("uncaughtException", (err) => {
  console.error("未捕获的异常:", err);
  // 这里可以进行清理工作
  process.exit(1); // 退出代码1表示因错误退出
});

// 捕获未处理的 Promise rejection
process.on("unhandledRejection", (reason, promise) => {
  console.error("未处理的 rejection:", promise, "原因:", reason);
});

// 监听退出事件
process.on("exit", (code) => {
  console.log(`进程即将退出，退出码: ${code}`);
});

// 监听信号终止事件 (如 Ctrl+C)
process.on("SIGINT", () => {
  console.log("收到 SIGINT 信号 (Ctrl+C)");
  process.exit(0);
});

process.on("SIGTERM", () => {
  console.log("收到 SIGTERM 信号");
  process.exit(0);
});

main();
